import 'package:flutter/material.dart';
import 'package:flutter_baselib/lib.dart';
import 'package:flutter_baselib/src/base/view_model/base_common_view_model.dart';
import 'package:flutter_baselib/src/const/constants.dart';

///@date:  2021/3/1 11:09
///@author:  lixu
///@description: ViewModel基类
///进入View页面时，需要http获取数据后才能显示UI的场景继承[BaseViewModel]类，配合[BaseView]使用
///泛型T：进入页面时，http获取数据对象的类型
///1.列表加载(分页加载)
///2.单个对象加载
///封装：通用加载页,集成了加载失败和加载为空的逻辑
abstract class BaseViewModel<T> extends BaseCommonViewModel {
  ///数据源:针对列表请求
  List<T> dataList;

  ///分页页数
  int _pageNum;

  ///分页加载：能否加载更多
  bool _canLoadMore;

  ///是否有分页加载功能
  ///默认true
  bool _isPageLoad;

  ///接口获取的是否是列表数据,否则就是单个数据对象
  ///默认true
  bool _isRequestListData;

  ///下拉刷新完成提示
  String _refreshedText = '刷新完成';

  String get refreshedText => _refreshedText;

  bool get canLoadMore => _canLoadMore;

  CancelToken _cancelToken;

  ///分页大小
  int _pageSize;

  ///数据源:针对单个对象请求
  T dataBean;

  BaseViewModel({bool isRequestListData = true, bool isPageLoad = true, int initPage = 0, int pageSize = Constants.pageSize}) {
    _isRequestListData = isRequestListData;
    _isPageLoad = isPageLoad;
    _pageNum = initPage;
    _pageSize = pageSize;
    _canLoadMore = true;
    LogUtils.i(getTag(), '调用构造方法:${toString()}');
  }

  int get pageNum => _pageNum;

  int get pageSize => _pageSize;

  ///获取http请求参数
  Map<String, dynamic> getRequestParams();

  ///获取http请求url
  String getUrl();

  ///请求失败是否显示错误提示
  bool isShowFailToast() {
    return true;
  }

  ///分页加载完所有数据时回调
  void onLoadCompleteAll() {
    ToastUtils.show('已加载完全部');
  }

  ///请求失败回调,子类根据需求重写
  ///[errorBean] http失败响应对象
  ///[isLoadMoreFail] 是否是加载更多失败
  void onErrorCallback(HttpErrorBean errorBean, {bool isLoadMoreFail = false}) {}

  void setCanLoadMore(bool value) {
    _canLoadMore = value;
  }

  ///加载数据
  ///第一次请求或下拉刷新时调用(请求参数设置为初始值)
  Future onLoading(BuildContext context) async {
    LogUtils.i(getTag(), 'getData');

    if (isLoading) {
      LogUtils.w(getTag(), 'getData is Loading');
      return;
    }

    isLoading = true;
    _refreshedText = '刷新成功';
    _cancelToken = CancelToken();

    if (_isRequestListData) {
      _pageNum = 1;

      ///请求列表数据
      await api.requestList<T>(
        getUrl(),
        params: getRequestParams(),
        isShowLoading: false,
        isShowFailToast: isShowFailToast(),
        cancelToken: _cancelToken,
        onSuccess: (List<T> list) {
          isLoading = false;
          _cancelToken = null;
          dataList = [];
          list = list ?? [];

          ///解析json
          dataList.addAll(list);

          if (_isPageLoad) {
            ///list分页加载
            if (list.length < _pageSize) {
              _canLoadMore = false;
            } else {
              _canLoadMore = true;
              _pageNum++;
            }
          } else {
            ///list没有分页加载
            _canLoadMore = false;
          }
        },
        onError: (HttpErrorBean errorBean) {
          isLoading = false;
          _cancelToken = null;
          _refreshedText = '刷新失败';
          onErrorCallback(errorBean);
        },
      );
    } else {
      ///请求单个数据对象
      await api.request<T>(
        getUrl(),
        params: getRequestParams(),
        isShowLoading: false,
        isShowFailToast: isShowFailToast(),
        cancelToken: _cancelToken,
        onSuccess: (T bean) {
          isLoading = false;
          _cancelToken = null;
          dataBean = bean;
        },
        onError: (HttpErrorBean errorBean) {
          isLoading = false;
          _cancelToken = null;
          _refreshedText = '刷新失败';
          onErrorCallback(errorBean);
        },
      );
    }
  }

  ///加载更多:针对分页加载
  Future onLoadingMore(context) async {
    LogUtils.i(getTag(), 'onLoadMore:$_canLoadMore');
    if (_canLoadMore) {
      if (isLoading) {
        LogUtils.w(getTag(), 'onLoadMore is Loading');
        return;
      }

      isLoading = true;
      _cancelToken = CancelToken();

      await api.requestList<T>(
        getUrl(),
        params: getRequestParams(),
        isShowLoading: false,
        onSuccess: (List<T> list) {
          isLoading = false;
          _cancelToken = null;
          if (list != null) {
            dataList ??= [];
            dataList.addAll(list);

            if (list.length < Constants.pageSize) {
              _canLoadMore = false;
            } else {
              _canLoadMore = true;
              _pageNum++;
            }
          }
        },
        onError: (HttpErrorBean errorBean) {
          isLoading = false;
          _cancelToken = null;
          onErrorCallback(errorBean, isLoadMoreFail: true);
        },
      );

      ///防止在加载更多时关闭页面,此时不需要notify
      if (!isDispose) {
        notifyListeners();
      } else {
        LogUtils.e(getTag(), '在调用notifyListeners()方法之前已经调用了dispose()方法');
      }
    } else {
      onLoadCompleteAll();
    }
  }

  ///请求失败:重试刷新页面
  void retryRefresh() {
    if (!isDispose) {
      notifyListeners();
    } else {
      LogUtils.e(getTag(), 'call retryRefresh() had dispose()');
    }
  }

  ///手动下拉刷新
  Future onPullToRefresh(BuildContext context) async {
    await onLoading(context);
    if (!isDispose) {
      notifyListeners();
    } else {
      LogUtils.e(getTag(), 'call onPullToRefresh() had dispose()');
    }
  }

  ///请求是否成功
  bool isSuccess() {
    if (_isRequestListData) {
      return dataList != null && dataList.length > 0;
    } else {
      return dataBean != null;
    }
  }

  ///请求是否失败
  bool isFail() {
    if (_isRequestListData) {
      return dataList == null;
    } else {
      return dataBean == null;
    }
  }

  ///请求是否为空
  bool isEmpty() {
    if (_isRequestListData) {
      return dataList == null || dataList.isEmpty;
    } else {
      return dataBean == null;
    }
  }

  @override
  void dispose() {
    super.dispose();
    api?.cancel(_cancelToken);
  }
}
